package com.gbiac.modules.monitor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gbiac.modules.monitor.api.IMonitorApi;
import com.gbiac.modules.monitor.entity.Equipment;
import com.gbiac.modules.monitor.entity.Seat;
import com.gbiac.modules.monitor.entity.SeatFaceLogin;
import com.gbiac.modules.monitor.event.AiDeviceCloseCameraTaskEvent;
import com.gbiac.modules.monitor.mapper.SeatFaceLoginMapper;
import com.gbiac.modules.monitor.param.UserCheckParam;
import com.gbiac.modules.monitor.service.AiDeviceService;
import com.gbiac.modules.monitor.service.IEquipmentService;
import com.gbiac.modules.monitor.service.ISeatFaceLoginService;
import com.gbiac.modules.monitor.service.ISeatService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.base.service.BaseCommonService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Description: 席位人脸登录
 * @Author: jeecg-boot
 * @Date:   2024-12-03
 * @Version: V1.0
 */
@Service
@Slf4j
public class SeatFaceLoginServiceImpl extends ServiceImpl<SeatFaceLoginMapper, SeatFaceLogin> implements ISeatFaceLoginService {

    @Resource
    @Lazy
    private IMonitorApi monitorApi;
    @Resource
    private ISeatService seatService;
    @Resource
    private IEquipmentService equipmentService;
    @Resource
    @Lazy
    private ISysBaseAPI sysBaseAPI;
    @Resource
    private BaseCommonService baseCommonService;
    @Resource
    @Lazy
    private AiDeviceService aiDeviceService;
    @Resource
    private ApplicationContext applicationContext;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startLogin(String seatId) {
        // 开始登录
        Seat seat = seatService.getById(seatId);
        if (seat == null) {
            throw new JeecgBootException("席位不存在");
        }
        SeatFaceLogin seatFaceLogin = getOne(new LambdaQueryWrapper<SeatFaceLogin>().eq(SeatFaceLogin::getSeatId, seatId));
        if (seatFaceLogin == null) {
            seatFaceLogin = new SeatFaceLogin();
            seatFaceLogin.setSeatId(seatId);
        }
        seatFaceLogin.setUserId(null);
        seatFaceLogin.setLoginTime(new Date());
        seatFaceLogin.setLoginSuccess(null);
        seatFaceLogin.setLoginResultMsg(null);

        saveOrUpdate(seatFaceLogin);
        // 调用设备开启人脸登录
        if (StringUtils.isBlank(seat.getEquipmentId())) {
            throw new JeecgBootException("席位未绑定人脸识别设备");
        }
        Equipment equipment = equipmentService.getById(seat.getEquipmentId());
        if (equipment == null) {
            throw new JeecgBootException("人脸设备设备不存在");
        }
        if (!aiDeviceService.openAiDevice(equipment.getCode())) {
            throw new JeecgBootException("开启人脸识别失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void clearLogin(String seatId, String userId) {
        SeatFaceLogin seatFaceLogin = getOne(new LambdaQueryWrapper<SeatFaceLogin>().eq(SeatFaceLogin::getSeatId, seatId).eq(SeatFaceLogin::getUserId, userId));
        if (seatFaceLogin == null) {
            return;
        }
        seatFaceLogin.setUserId(null);
        seatFaceLogin.setLoginTime(null);
        seatFaceLogin.setLoginSuccess(null);
        seatFaceLogin.setLoginResultMsg(null);
        updateById(seatFaceLogin);

        closeAiDeviceCatchException(seatId);
    }

    private void closeAiDeviceCatchException(String seatId) {
        Seat seat = seatService.getById(seatId);
        if (seat == null) {
            return;
        }
        if (StringUtils.isBlank(seat.getEquipmentId())) {
            return;
        }
        Equipment equipment = equipmentService.getById(seat.getEquipmentId());
        if (equipment == null) {
            return;
        }
        // 调用设备接口停止摄像头识别,异步
//        try {
//            Boolean result = aiDeviceService.closeCameraTask(equipment.getCode());
//            if (!result) {
//                log.error("关闭人脸失败设备停止人脸失败失败");
//            }
//        } catch (Exception e) {
////            e.printStackTrace();
//            log.error("关闭人脸失败设备停止人脸失败失败：", e);
//        }
        applicationContext.publishEvent(new AiDeviceCloseCameraTaskEvent(equipment.getCode(),5));
    }

    @Override
//    @Transactional(rollbackFor = Exception.class, noRollbackFor = JeecgBootException.class)
    public boolean loginCallback(String seatId, String userId) {
        if (StringUtils.isEmpty(seatId)) {
            throw new JeecgBootException("seatId 不能为空");
        }
        if (StringUtils.isEmpty(userId)) {
            throw new JeecgBootException("userId 不能为空");
        }

        SeatFaceLogin seatFaceLogin = getOne(new LambdaQueryWrapper<SeatFaceLogin>().eq(SeatFaceLogin::getSeatId, seatId));
        if (seatFaceLogin == null) {
            throw new JeecgBootException("seatId 对应席位未发起人脸登录请求");
        }
        LoginUser user = sysBaseAPI.getUserById(userId);
        // 情况1：根据用户信息查询，该用户不存在
        if (user == null) {
            baseCommonService.addLog("用户人脸登录失败，用户不存在！", CommonConstant.LOG_TYPE_1, null);
            seatFaceLogin.loginFailure("该用户不存在，请注册");
            return false;
        }
        // 情况2：根据用户信息查询，该用户已注销
        if (CommonConstant.DEL_FLAG_1.equals(user.getDelFlag())) {
            baseCommonService.addLog("用户人脸登录失败，用户名:" + user.getUsername() + "已注销！", CommonConstant.LOG_TYPE_1, null);
            seatFaceLogin.loginFailure("该用户已注销");
            return false;
        }
        // 情况3：根据用户信息查询，该用户已冻结
        if (CommonConstant.USER_FREEZE.equals(user.getStatus())) {
            baseCommonService.addLog("用户人脸登录失败，用户名:" + user.getUsername() + "已冻结！", CommonConstant.LOG_TYPE_1, null);
            seatFaceLogin.loginFailure("该用户已冻结");
            return false;
        }
        Seat seat = seatService.getById(seatId);
        if (seat == null) {
            throw new JeecgBootException("seatId 不存在");
        }
        // TODO 监测掌静脉打卡记录
        try {
            // 进行上岗打卡，如果上岗打卡报错，那就是登录失败
            monitorApi.checkIn(new UserCheckParam(user.getUsername(), seat.getIp()));
            seatFaceLogin.loginSuccess(userId);
            // 添加日志
            baseCommonService.addLog("用户名: " + user.getUsername() + ",人脸登录成功！", CommonConstant.LOG_TYPE_1, null);
            updateById(seatFaceLogin);
            return true;
        } catch (Exception e) {
            // 登录失败，捕获异常，记录登录状态和异常信息
            seatFaceLogin.loginFailure(e.getMessage());
        }
        updateById(seatFaceLogin);
        return false;
    }

    @Override
    public SeatFaceLogin getLoginResult(String seatId) {
        // 查询人脸登录结果
        SeatFaceLogin seatFaceLogin = getOne(new LambdaQueryWrapper<SeatFaceLogin>().eq(SeatFaceLogin::getSeatId, seatId));
        if (seatFaceLogin == null) {
            throw new JeecgBootException("seatId 对应席位未发起人脸登录请求");
        }
        return seatFaceLogin;
    }
}
